﻿
/*
 =====================================================
 * Copyright © 2022 IceToad All rights reserved.
 * 作者: IceToad
 * 创建时间: 2022/11/09 10:09:09
 * 版本: v1.0.1
 * 版权说明: 引用或转载请注明源
 * ----------------------------------------------------
 * 文件名: INIHelper.cs
 * 程序集: YYIniHelper
 * 文件功能: 提供对INI文件的操作
 * CSDN：https://blog.csdn.net/weixin_44312699
 * Gitee：https://gitee.com/icetoads
 * 语雀：https://www.yuque.com/icetoad
 * 公众号：【冰蟾DotNet】（后台可留言）
 * ----------------------------------------------------
 * 说明：
 * 本项目提供功能有限，难免有考虑不到的情况，如发现错误或有什么建议，欢迎指正
 ======================================================
*/
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace YYIniHelper
{
    /// <summary>
    /// INI文件操作类
    /// </summary>
    public class INIHelper
    {
        /// <summary>
        /// 修改INI文件内容
        /// </summary>
        /// <param name="lpApplicationName">节点名称(段落名称)section</param>
        /// <param name="lpKeyName">要设置的项名，Key</param>
        /// <param name="lpString">要写入的新字符串Value</param>
        /// <param name="lpFileName">INI文件晚挣路径</param>
        /// <returns>0表示失败，非零表示成功</returns>
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString
            (string lpApplicationName, string lpKeyName, string lpString, string lpFileName);

        /// <summary>
        /// 获取INI中指定字符串
        /// </summary>
        /// <param name="lpAppName">节点名称(段落名称)section</param>
        /// <param name="lpKeyName">项名，Key</param>
        /// <param name="lpDefault">未找到指定项时返回的默认值</param>
        /// <param name="lpReturnedString">指定一个字符串缓冲区，长度至少为nSize</param>
        /// <param name="nSize">指定装载到lpReturnedString缓冲区的最大字符数量</param>
        /// <param name="lpFileName">INI文件路径</param>
        /// <returns>复制到lpReturnedString中的字节数量</returns>
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString
            (string lpAppName,
            string lpKeyName,
            string lpDefault,
            StringBuilder lpReturnedString,
            int nSize,
            string lpFileName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern uint GetPrivateProfileSection
            (string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);


        /// <summary>
        /// 判断指定的路径是否合法
        /// </summary>
        /// <param name="filename">INI文件路径</param>
        /// <returns></returns>
        private static bool IsLegalIniFile(string filename)
        {
            if (string.IsNullOrWhiteSpace(filename)) return false;
            if (Path.GetExtension(filename) != ".ini") return false;
            return true;
        }


        /// <summary>
        /// 判断指定INI文件是否存在，不存在则创建
        /// </summary>
        /// <param name="fileName">INI文件路径</param>
        /// <param name="isCreate">是否创建文件</param>
        /// <returns>文件存在或成功创建返回true，文件不存在或未创建成功返回false</returns>
        public static bool IsHaveIniFileAndCreate(string fileName, bool isCreate = false)
        {
            //判断路径是否合法
            if (!IsLegalIniFile(fileName)) return false;

            //判断文件是否存在
            if (File.Exists(fileName)) return true;

            //创建文件
            if (isCreate)
            {
                try
                {
                    FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
                    fs.Close();
                    fs.Dispose();
                    if (File.Exists(fileName)) return true;
                }
                catch (Exception ex)
                {
                    YYLogHelper.LogHelper.WriteLogError(Environment.NewLine + "[YYIniHelper.INIHelper.IsHaveIniFileAndCreate]", ex);
                }
            }

            return false;
        }

        /// <summary>
        /// 修改ini，
        /// </summary>
        /// <param name="section">节点/段落名称</param>
        /// <param name="key">项/Key名称</param>
        /// <param name="value">值</param>
        /// <param name="filePath">ini文件路径</param>
        /// <param name="IsCreate">是否创建文件</param>
        public static void WriteIniKeys(string section, string key, string value, string filePath, bool IsCreate = false)
        {
            //判断文件路径是否存在
            if (IsHaveIniFileAndCreate(filePath, IsCreate))
            {
                if (string.IsNullOrWhiteSpace(section))
                {
                    YYLogHelper.LogHelper.WriteLogError(Environment.NewLine + $"[YYIniHelper.INIHelper.WriteIniKeys]：修改配置文件失败，节点名称为空。section={section}");
                }
                else
                {
                    WritePrivateProfileString(section, key, value, filePath);
                }
            }
            else
            {
                YYLogHelper.LogHelper.WriteLogError(Environment.NewLine + "[YYIniHelper.INIHelper.WriteIniKeys]：修改配置文件失败，未知的文件路径。");
            }
        }


        /// <summary>
        /// 根据section，key取值
        /// </summary>
        /// <param name="section">节点/段落名称</param>
        /// <param name="key">项/Key名称</param>
        /// <param name="filePath">ini文件路径</param>
        /// <returns>>返回指定内容，若不存在则返回空字符串</returns>
        public static string ReadIniKeys(string section, string key, string filePath)
        {
            return ReadIniKeys(section, key, "", filePath);
        }


        /// <summary>
        /// 根据section，key取值,并设置默认值
        /// </summary>
        /// <param name="section">节点/段落名称</param>
        /// <param name="key">项/Key名称</param>
        /// <param name="def">默认值</param>
        /// <param name="filePath">文件路径</param>
        /// <param name="IsCreate">是否创建默认配置</param>
        /// <returns>返回指定内容，若不存在则返回默认值def</returns>
        private static string ReadIniKeys(string section, string key, string def, string filePath, bool IsCreate = false)
        {
            StringBuilder temp = new StringBuilder(1024);
            try
            {
                GetPrivateProfileString(section, key, def, temp, 1024, filePath);
            }
            catch (Exception ex)
            {
                YYLogHelper.LogHelper.WriteLogError(Environment.NewLine + "[YYIniHelper.INIHelper.ReadIniKeys]", ex);
            }
            //创建节点
            if (IsCreate && temp.ToString() == def)
            {
                YYLogHelper.LogHelper.WriteLogError(Environment.NewLine + $@"[YYIniHelper.INIHelper.ReadIniKeys]:创建默认配置:section={section}, key={key}, valueDef={def}, filePath={filePath};");
                WriteIniKeys(section, key, def, filePath, IsCreate);
            }

            return temp.ToString();
        }


    }
}